package com.sc.nft.dao;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sc.nft.entity.DigitalCollectionProductInfo;
import com.sc.nft.entity.vo.*;
import com.sc.nft.entity.vo.salvageEvents.SalvageProductPageVO;
import com.sc.nft.enums.ClassifyType;
import com.sc.nft.enums.CommodityType;
import com.sc.nft.enums.NFTProductShowSalvagePrefectureEnum;
import com.sc.nft.mapper.DigitalCollectionProductInfoMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * (sc_digital_collection_product_info)数据DAO
 *
 * @author Sun
 * @description 由 Mybatisplus Code Generator 创建
 * @since 2022-05-30 13:42:06
 */
@Slf4j
@Repository
public class DigitalCollectionProductInfoDao extends ServiceImpl<DigitalCollectionProductInfoMapper, DigitalCollectionProductInfo> {
    @Resource
    private DigitalCollectionProductInfoMapper digitalCollectionProductInfoMapper;

    public List<HashMap> findAllBlindBox(int isIosShow) {
        return baseMapper.findAllBlindBox(isIosShow);
    }

    public List<ALLCatenaVO> findBlindBoxCatena(int isIosShow) {
        return baseMapper.findBlindBoxCatena(isIosShow);
    }

    public DigitalCollectionProductInfo getProductDetails(Long productId, Integer typeClassify, Integer commodityType) {
        LambdaQueryWrapper<DigitalCollectionProductInfo> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.eq(DigitalCollectionProductInfo::getId, productId).eq(DigitalCollectionProductInfo::getIsDelete, Boolean.FALSE);
        productWrapper.eq(DigitalCollectionProductInfo::getStatus, Boolean.TRUE);
        productWrapper.eq(DigitalCollectionProductInfo::getTypeClassify, typeClassify);
        productWrapper.eq(DigitalCollectionProductInfo::getCommodityType, commodityType);
        return getOne(productWrapper);
    }


    public List<HomePageDigitalCollectionProductVO> getTop10DigitalCollection(int isIosShow) {
        return baseMapper.getTop10DigitalCollection(isIosShow);
    }

    public Page<IntegralExchangeProductVO> getIntegralExchangeList(Page page) {
        return digitalCollectionProductInfoMapper.getIntegralExchangeList(page);
    }

    public DigitalCollectionProductInfo getExchangeProduct(Long productId) {
        LambdaQueryWrapper<DigitalCollectionProductInfo> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.eq(DigitalCollectionProductInfo::getId, productId);
        productWrapper.eq(DigitalCollectionProductInfo::getStatus, Boolean.TRUE);
        productWrapper.eq(DigitalCollectionProductInfo::getCommodityType, 2);
        return getOne(productWrapper);
    }

    public DigitalCollectionProductInfo getairdropProduct(Long productId) {
        LambdaQueryWrapper<DigitalCollectionProductInfo> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.eq(DigitalCollectionProductInfo::getId, productId);
        productWrapper.eq(DigitalCollectionProductInfo::getStatus, Boolean.TRUE);
        productWrapper.eq(DigitalCollectionProductInfo::getCommodityType, CommodityType.AIR_DROP.getCode());
        return getOne(productWrapper);
    }

    public DigitalCollectionProductInfo getProductByCommodityType(Long productId, CommodityType commodityType) {
        LambdaQueryWrapper<DigitalCollectionProductInfo> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.eq(DigitalCollectionProductInfo::getId, productId);
        productWrapper.eq(DigitalCollectionProductInfo::getCommodityType, commodityType.getCode());
        return getOne(productWrapper);
    }


    public DigitalCollectionProductInfo getProductDetails(Long productId, int isIosShow) {
        LambdaQueryWrapper<DigitalCollectionProductInfo> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.eq(DigitalCollectionProductInfo::getStatus, true);
        productWrapper.eq(DigitalCollectionProductInfo::getId, productId);
        productWrapper.in(DigitalCollectionProductInfo::getCommodityType, CommodityType.PRODUCT, CommodityType.LOTTERY, CommodityType.DAO_PRODUCT, CommodityType.COPYRIGHT_COMMODITY);
        productWrapper.eq(DigitalCollectionProductInfo::getIsIosShow, isIosShow);
        return getOne(productWrapper);
    }

    public DigitalCollectionProductInfo getSubscribeProductDetails(Long productId, int isIosShow) {
        LambdaQueryWrapper<DigitalCollectionProductInfo> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.eq(DigitalCollectionProductInfo::getStatus, true);
        productWrapper.eq(DigitalCollectionProductInfo::getId, productId);
        productWrapper.eq(DigitalCollectionProductInfo::getCommodityType, CommodityType.SUBSCRIBE_COMMODITY);
        productWrapper.eq(DigitalCollectionProductInfo::getIsIosShow, isIosShow);
        return getOne(productWrapper);
    }


    public DigitalCollectionProductInfo getAuctionProductDetails(Long productId, int isIosShow) {
        LambdaQueryWrapper<DigitalCollectionProductInfo> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.eq(DigitalCollectionProductInfo::getStatus, true);
        productWrapper.eq(DigitalCollectionProductInfo::getId, productId);
        productWrapper.eq(DigitalCollectionProductInfo::getCommodityType, CommodityType.AUCTION_PRODUCT);
        productWrapper.eq(DigitalCollectionProductInfo::getIsIosShow, isIosShow);
        return getOne(productWrapper);
    }

    public DigitalCollectionProductInfo getBlindBoxDetails(Long productId, int isIosShow) {
        LambdaQueryWrapper<DigitalCollectionProductInfo> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.eq(DigitalCollectionProductInfo::getStatus, true);
        productWrapper.eq(DigitalCollectionProductInfo::getId, productId);
        productWrapper.eq(DigitalCollectionProductInfo::getTypeClassify, 2);
        productWrapper.eq(DigitalCollectionProductInfo::getCommodityType, 1);
        productWrapper.eq(DigitalCollectionProductInfo::getIsIosShow, isIosShow);
        return getOne(productWrapper);
    }

    public DigitalCollectionProductInfo getAllBlindBoxDetails(Long productId, int isIosShow) {
        LambdaQueryWrapper<DigitalCollectionProductInfo> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.eq(DigitalCollectionProductInfo::getId, productId);
        productWrapper.eq(DigitalCollectionProductInfo::getTypeClassify, 2);
        productWrapper.eq(DigitalCollectionProductInfo::getIsIosShow, isIosShow);
        return getOne(productWrapper);
    }

    public DigitalCollectionProductInfo getAllBlindProductDetails(Long productId, int isIosShow) {
        LambdaQueryWrapper<DigitalCollectionProductInfo> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.eq(DigitalCollectionProductInfo::getId, productId);
        productWrapper.eq(DigitalCollectionProductInfo::getTypeClassify, 1);
        productWrapper.eq(DigitalCollectionProductInfo::getIsIosShow, isIosShow);
        return getOne(productWrapper);
    }

    /**
     * 减去可售卖数量
     * 加上已出售数量
     *
     * @param productId
     * @return
     */
    public Boolean subLaveNum(Long productId) {
        UpdateWrapper<DigitalCollectionProductInfo> wrapper = new UpdateWrapper<>();
        wrapper.setSql("already_num=already_num + " + 1);
        wrapper.setSql("lave_num = lave_num - " + 1);
        wrapper.eq("id", productId);
        return update(wrapper);
    }

    public Page<DigitalCollectionProductVO> getMallPageList(Page page, Long catenaId, Integer typeClassify, String num, String count, String time, int isIosShow) {
        return digitalCollectionProductInfoMapper.getMallPageList(page, catenaId, typeClassify, num, time, count, isIosShow);
    }

    public Page<DigitalCollectionProductVO> searchProductList(Page page, String firstTitle, Integer typeClassify, int isIosShow) {
        return digitalCollectionProductInfoMapper.searchProductList(page, firstTitle, typeClassify, isIosShow);
    }

    public Page<PageProductVO> pageProduct(String firstTitle, String productUuid, Boolean status, Boolean isSoldOut, Integer commodityType, Integer classifyType, int pageNo, int pageSize) {
        return digitalCollectionProductInfoMapper.pageProduct(new Page(pageNo, pageSize), firstTitle, productUuid, commodityType, classifyType, status, isSoldOut);
    }

    public List<DigitalCollectionProductInfo> inviteTaskProductList() {
        LambdaQueryWrapper<DigitalCollectionProductInfo> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.eq(DigitalCollectionProductInfo::getCommodityType, CommodityType.INVITE_TASKS);
        productWrapper.eq(DigitalCollectionProductInfo::getStatus, Boolean.TRUE);
        productWrapper.eq(DigitalCollectionProductInfo::getIsEnable, Boolean.TRUE);
        productWrapper.eq(DigitalCollectionProductInfo::getIsSoldOut, Boolean.FALSE);
        productWrapper.eq(DigitalCollectionProductInfo::getIsSoldOut, Boolean.FALSE);
        return list(productWrapper);
    }

    /*public List<DigitalCollectionProductInfo> airdropGrantProduct(Page page,String firstTitle, String productUuid, Integer typeClassify) {
        LambdaQueryWrapper<DigitalCollectionProductInfo> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.eq(productUuid != null, DigitalCollectionProductInfo::getDigitalCollectionProductInfoUuid, productUuid);
        productWrapper.eq(firstTitle != null, DigitalCollectionProductInfo::getFirstTitle, firstTitle);
        productWrapper.eq(typeClassify != null, DigitalCollectionProductInfo::getTypeClassify, typeClassify);
        productWrapper.eq(DigitalCollectionProductInfo::getCommodityType, CommodityType.AIR_DROP.getCode());
        productWrapper.eq(DigitalCollectionProductInfo::getIsSoldOut, Boolean.FALSE);
        productWrapper.eq(DigitalCollectionProductInfo::getStatus, Boolean.TRUE);
        return list(productWrapper);
    }*/

    public Boolean updateProductStatus(Long id, Boolean status, Boolean isEnable) {
        UpdateWrapper<DigitalCollectionProductInfo> wrapper = new UpdateWrapper<>();
        wrapper.set(status != null, "status", status);
        wrapper.set(isEnable != null, "is_enable", isEnable);
        if (ObjectUtil.isNotEmpty(isEnable)) {
            if (isEnable) {
                wrapper.set("product_type", 1);
            } else {
                wrapper.set("product_type", 4);
            }
        }
        wrapper.eq("id", id);
        return update(wrapper);
    }


    public DigitalCollectionProductInfo getByProductUuId(String productUuId) {
        LambdaQueryWrapper<DigitalCollectionProductInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DigitalCollectionProductInfo::getDigitalCollectionProductInfoUuid, productUuId);
        return getOne(wrapper);
    }

    public List<PrivilegeProductVO> privilegeProductList(Integer commodityType) {
        return baseMapper.privilegeProductList(commodityType);
    }

    public List<DigitalCollectionProductInfo> getByCollectionId(Long collectionId) {
        LambdaQueryWrapper<DigitalCollectionProductInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DigitalCollectionProductInfo::getRelationId, collectionId);
        wrapper.eq(DigitalCollectionProductInfo::getStatus, Boolean.TRUE);
        wrapper.in(DigitalCollectionProductInfo::getCommodityType, CommodityType.SYNTHESIS, CommodityType.PRIVILEGE);
        return list(wrapper);
    }

    public List<DigitalCollectionProductInfo> getAllPrivilegeProduct() {
        LambdaQueryWrapper<DigitalCollectionProductInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DigitalCollectionProductInfo::getStatus, Boolean.TRUE);
        wrapper.in(DigitalCollectionProductInfo::getCommodityType, CommodityType.SYNTHESIS, CommodityType.PRIVILEGE);
        return list(wrapper);
    }

    public List<DigitalCollectionProductInfo> selectByCollectionId(Long collectionId, ClassifyType classifyType) {
        LambdaQueryWrapper<DigitalCollectionProductInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DigitalCollectionProductInfo::getRelationId, collectionId);
        wrapper.eq(DigitalCollectionProductInfo::getTypeClassify, classifyType);
        return list(wrapper);
    }

    public DigitalCollectionProductInfo getOneByProductIdAndCommodityType(Long productId, CommodityType cdkProduct) {
        LambdaQueryWrapper<DigitalCollectionProductInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DigitalCollectionProductInfo::getId, productId);
        wrapper.eq(DigitalCollectionProductInfo::getCommodityType, cdkProduct);
        return getOne(wrapper);
    }

    public List<DigitalCollectionProductInfo> getAllNeedBackStock() {
        LambdaQueryWrapper<DigitalCollectionProductInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DigitalCollectionProductInfo::getProductType, 3);
        wrapper.eq(DigitalCollectionProductInfo::getIsBackStock, Boolean.FALSE);
        return list(wrapper);
    }

    public List<DigitalCollectionProductInfo> getAllNoBeginProduct(DateTime time) {
        LambdaQueryWrapper<DigitalCollectionProductInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DigitalCollectionProductInfo::getStatus, Boolean.TRUE);
        wrapper.eq(DigitalCollectionProductInfo::getIsSoldOut, Boolean.FALSE);
        wrapper.eq(DigitalCollectionProductInfo::getProductType, 4);
        wrapper.notIn(DigitalCollectionProductInfo::getCommodityType, Arrays.asList(CommodityType.CDK_PRODUCT, CommodityType.AIR_DROP));
        wrapper.lt(DigitalCollectionProductInfo::getBeginTime, time);
        return list(wrapper);
    }

    public Boolean openProductBegin(Long productId) {
        UpdateWrapper<DigitalCollectionProductInfo> wrapper = new UpdateWrapper<>();
        wrapper.eq("id", productId);
        wrapper.eq("status", Boolean.TRUE);
        wrapper.set("product_type", 1);
        return update(wrapper);
    }

    public List<DigitalCollectionProductInfo> getAllNoEndProduct() {
        LambdaQueryWrapper<DigitalCollectionProductInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DigitalCollectionProductInfo::getStatus, Boolean.TRUE);
        wrapper.eq(DigitalCollectionProductInfo::getProductType, 1);
        return list(wrapper);
    }

    public Boolean closeProductEnd(Long productId) {
        UpdateWrapper<DigitalCollectionProductInfo> wrapper = new UpdateWrapper<>();
        wrapper.eq("id", productId);
        wrapper.eq("status", Boolean.TRUE);
        wrapper.set("is_sold_out", Boolean.TRUE);
        wrapper.set("product_type", 3);
        return update(wrapper);
    }

    public Boolean updateIsBackStock(Long productId) {
        UpdateWrapper<DigitalCollectionProductInfo> wrapper = new UpdateWrapper<>();
        wrapper.eq("id", productId);
        wrapper.set("is_back_stock", Boolean.TRUE);
        return update(wrapper);
    }

    /**
     * 分页按类型查询商品列表(上架中)
     *
     * @param page
     * @param commodityType
     * @param firstTitle
     * @param typeClassify
     * @return
     */
    public Page<AssociateProductListByCommodityTypeVO> getAssociateProductListByCommodityType(Page page, CommodityType commodityType, String firstTitle, ClassifyType typeClassify) {
        return baseMapper.getAssociateProductListByCommodityType(page, commodityType.getCode(), firstTitle, typeClassify.getCode(), Boolean.TRUE);
    }

    /**
     * 分页按类型查询商品列表(所有)
     *
     * @param page
     * @param commodityType
     * @param firstTitle
     * @param typeClassify
     * @return
     */
    public Page<AssociateProductListByCommodityTypeVO> getAllAssociateProductListByCommodityType(Page page, CommodityType commodityType, String firstTitle, ClassifyType typeClassify) {
        if (ObjectUtil.isNull(typeClassify)) {
            return baseMapper.getAllAssociateProductListByCommodityType(page, commodityType.getCode(), firstTitle, null, null);
        }
        return baseMapper.getAllAssociateProductListByCommodityType(page, commodityType.getCode(), firstTitle, typeClassify.getCode(), null);
    }

    public Page<BoxCollectionByUserCreatorIdVO> getPageBoxCollectionByUserCreatorId(Long userCreatorId, Integer pageNo, Integer pageSize) {
        return baseMapper.getPageBoxCollectionByUserCreatorId(new Page(pageNo, pageSize), userCreatorId);
    }

    public Page<SalvageProductPageVO> getSalvageProductPage(NFTProductShowSalvagePrefectureEnum showSalvagePrefecture, Integer pageNo, Integer pageSize) {
        return baseMapper.getSalvageProductPage(new Page(pageNo, pageSize), ObjectUtil.isNull(showSalvagePrefecture) ? 1 : showSalvagePrefecture.getCode());
    }


    public List<DigitalCollectionProductInfo> selectByCollectionIdAndCommodityType(Long collectionId, CommodityType commodityType) {
        LambdaQueryWrapper<DigitalCollectionProductInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DigitalCollectionProductInfo::getRelationId, collectionId);
        wrapper.eq(DigitalCollectionProductInfo::getCommodityType, commodityType);
        wrapper.eq(DigitalCollectionProductInfo::getStatus, Boolean.TRUE);
        return list(wrapper);
    }

    public List<DigitalCollectionProductInfo> listByNameWithDaoId(String firstTitle, Long daoId) {
        LambdaQueryWrapper<DigitalCollectionProductInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(DigitalCollectionProductInfo::getId, DigitalCollectionProductInfo::getFirstTitle, DigitalCollectionProductInfo::getCreationContent);
        wrapper.eq(DigitalCollectionProductInfo::getUserCreatorId, daoId);
        wrapper.like(DigitalCollectionProductInfo::getFirstTitle, firstTitle);
        return list(wrapper);
    }


    public Boolean isExist(Long relationId) {
        LambdaQueryWrapper<DigitalCollectionProductInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DigitalCollectionProductInfo::getStatus, Boolean.TRUE);
        wrapper.eq(DigitalCollectionProductInfo::getRelationId, relationId);
        wrapper.in(DigitalCollectionProductInfo::getCommodityType, CommodityType.PRODUCT, CommodityType.LOTTERY);
        wrapper.eq(DigitalCollectionProductInfo::getTypeClassify, ClassifyType.COLLECTION);
        return count(wrapper) > 0;
    }

    public void soldOut(Long id) {
        baseMapper.soldOut(id);
    }

    public DigitalCollectionProductInfo getByPanelIdOne(Long panelId) {
        return lambdaQuery().eq(DigitalCollectionProductInfo::getShareProfitPanelId, panelId).last("limit 1").one();
    }


    /**
     * 获取某个藏品是否为分解藏品
     *
     * @param collectionId
     * @return
     */
    public Boolean getWhetherToBreakDownTheCollection(Long collectionId) {
        return baseMapper.getWhetherToBreakDownTheCollection(collectionId) > 0;
    }

    public List<Long> getEquityId(List<Long> equityId) {
        LambdaQueryWrapper<DigitalCollectionProductInfo> wrapper = Wrappers.lambdaQuery();
        wrapper.select(DigitalCollectionProductInfo::getId);
        wrapper.in(DigitalCollectionProductInfo::getRelationId, equityId);
        wrapper.groupBy(DigitalCollectionProductInfo::getId);
        return list(wrapper).stream().map(DigitalCollectionProductInfo::getId).collect(Collectors.toList());
    }


    public Page<AirdropGrantproductVO> airdropGrantProduct(Page page, String firstTitle, String productUuid, Integer typeClassify, Integer commodityType) {
        return baseMapper.airdropGrantProduct(page, firstTitle, productUuid, typeClassify, commodityType);

    }

    /**
     * 获取芯片商品
     *
     * @param page
     * @param firstTitle
     * @return
     */
    public Page<AssociateProductListByCommodityTypeVO> getAssociateChipProductList(Page page, String firstTitle) {
        return baseMapper.getAssociateChipProductList(page, firstTitle);
    }

    /**
     * 查询商品无关状态
     * @param productId
     * @return
     */
    public DigitalCollectionProductInfo getProductById(Long productId) {
        LambdaQueryWrapper<DigitalCollectionProductInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DigitalCollectionProductInfo::getId, productId);
        return getOne(queryWrapper);
    }
}